home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / dummydos.c < prev    next >
C/C++ Source or Header  |  1994-09-09  |  15KB  |  597 lines

  1. /*
  2.  * Program:    Dummy routines for DOS
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    24 May 1993
  13.  * Last Edited:    9 September 1994
  14.  *
  15.  * Copyright 1994 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36.  
  37. #include <ctype.h>
  38. #include <stdio.h>
  39. #include <errno.h>
  40. #include <fcntl.h>
  41. #include "mail.h"
  42. #include "osdep.h"
  43. #include <sys\stat.h>
  44. #include <dos.h>
  45. #include <io.h>
  46. #include "dummy.h"
  47. #include "misc.h"
  48.  
  49. long dummy_badname (char *tmp,char *s);
  50.  
  51. /* Dummy routines */
  52.  
  53.  
  54. /* Driver dispatch used by MAIL */
  55.  
  56. DRIVER dummydriver = {
  57.   "dummy",            /* driver name */
  58.   (DRIVER *) NIL,        /* next driver */
  59.   dummy_valid,            /* mailbox is valid for us */
  60.   dummy_parameters,        /* manipulate parameters */
  61.   dummy_find,            /* find mailboxes */
  62.   dummy_find_bboards,        /* find bboards */
  63.   dummy_find_all,        /* find all mailboxes */
  64.   dummy_find_all_bboards,    /* find all bboards */
  65.   dummy_subscribe,        /* subscribe to mailbox */
  66.   dummy_unsubscribe,        /* unsubscribe from mailbox */
  67.   dummy_subscribe_bboard,    /* subscribe to bboard */
  68.   dummy_unsubscribe_bboard,    /* unsubscribe from bboard */
  69.   dummy_create,            /* create mailbox */
  70.   dummy_delete,            /* delete mailbox */
  71.   dummy_rename,            /* rename mailbox */
  72.   dummy_open,            /* open mailbox */
  73.   dummy_close,            /* close mailbox */
  74.   dummy_fetchfast,        /* fetch message "fast" attributes */
  75.   dummy_fetchflags,        /* fetch message flags */
  76.   dummy_fetchstructure,        /* fetch message structure */
  77.   dummy_fetchheader,        /* fetch message header only */
  78.   dummy_fetchtext,        /* fetch message body only */
  79.   dummy_fetchbody,        /* fetch message body section */
  80.   dummy_setflag,        /* set message flag */
  81.   dummy_clearflag,        /* clear message flag */
  82.   dummy_search,            /* search for message based on criteria */
  83.   dummy_ping,            /* ping mailbox to see if still alive */
  84.   dummy_check,            /* check for new messages */
  85.   dummy_expunge,        /* expunge deleted messages */
  86.   dummy_copy,            /* copy messages to another mailbox */
  87.   dummy_move,            /* move messages to another mailbox */
  88.   dummy_append,            /* append string message to mailbox */
  89.   dummy_gc            /* garbage collect stream */
  90. };
  91.  
  92.  
  93.                 /* prototype stream */
  94. MAILSTREAM dummyproto = {&dummydriver};
  95.  
  96.                 /* driver parameters */
  97. static char *file_extension = NIL;
  98.  
  99. /* Dummy validate mailbox
  100.  * Accepts: mailbox name
  101.  * Returns: our driver if name is valid, NIL otherwise
  102.  */
  103.  
  104. DRIVER *dummy_valid (char *name)
  105. {
  106.   char tmp[MAILTMPLEN];
  107.   struct stat sbuf;
  108.                 /* must be valid local mailbox */
  109.   return (name && *name && (*name != '*') && (*name != '{') &&
  110.                 /* INBOX is always accepted */
  111.       ((!strcmp (ucase (strcpy (tmp,name)),"INBOX")) ||
  112.                 /* so is any valid file */
  113.        (mailboxfile (tmp,name) && !stat (tmp,&sbuf))))
  114.     ? &dummydriver : NIL;
  115. }
  116.  
  117.  
  118. /* Dummy manipulate driver parameters
  119.  * Accepts: function code
  120.  *        function-dependent value
  121.  * Returns: function-dependent return value
  122.  */
  123.  
  124. void *dummy_parameters (long function,void *value)
  125. {
  126.   switch ((int) function) {
  127.   case SET_EXTENSION:
  128.     if (file_extension) fs_give ((void **) &file_extension);
  129.     if (*(char *) value) file_extension = cpystr ((char *) value);
  130.     break;
  131.   case GET_EXTENSION:
  132.     value = (void *) file_extension;
  133.     break;
  134.   default:
  135.     value = NIL;        /* error case */
  136.     break;
  137.   }
  138.   return value;
  139. }
  140.  
  141. /* Dummy find list of subscribed mailboxes
  142.  * Accepts: mail stream
  143.  *        pattern to search
  144.  */
  145.  
  146. void dummy_find (MAILSTREAM *stream,char *pat)
  147. {
  148.   void *sdb = NIL;
  149.   char *t = sm_read (&sdb);
  150.   if (t) do if ((*t != '{') && strcmp (t,"INBOX") && pmatch (t,pat))
  151.     mm_mailbox (t);
  152.   while (t = sm_read (&sdb));    /* read subscription database */
  153. }
  154.  
  155.  
  156. /* Dummy find list of subscribed bboards
  157.  * Accepts: mail stream
  158.  *        pattern to search
  159.  */
  160.  
  161. void dummy_find_bboards (MAILSTREAM *stream,char *pat)
  162. {
  163.                 /* return silently */
  164. }
  165.  
  166. /* Dummy find list of all mailboxes
  167.  * Accepts: mail stream
  168.  *        pattern to search
  169.  */
  170.  
  171. void dummy_find_all (MAILSTREAM *stream,char *pat)
  172. {
  173.   struct find_t f;
  174.   char *s,tmp[MAILTMPLEN],file[MAILTMPLEN];
  175.   int i = 0;
  176.   int doinbox = T;
  177.                 /* directory specified in pattern? */
  178.   if ((s = strrchr (pat,'\\')) || (*(s = pat + 1) == ':')) {
  179.     strncpy (file,pat,i = (++s) - pat);
  180.     file[i] = '\0';        /* tie off prefix */
  181.   }
  182.                 /* make fully-qualified file name */
  183.   if (!mailboxfile (tmp,pat)) return;
  184.                 /* all files in directory */
  185.   strcpy ((s = strrchr (tmp,'\\')) ? s : tmp + 2,"\\*.");
  186.   strcat (s,file_extension ? file_extension : "*");
  187.                 /* loop through matching files */
  188.   if (!_dos_findfirst (tmp,_A_NORMAL,&f)) do {
  189.                 /* suppress extension */
  190.     if (file_extension && (s = strchr (f.name,'.'))) *s = '\0';
  191.     strcpy (file + i,f.name);    /* build file name */
  192.     if (!strcmp (f.name,"INBOX")) doinbox = 0;
  193.     if (pmatch (file,pat)) mm_mailbox (file);
  194.   } while (!_dos_findnext (&f));
  195.                 /* always an INBOX */
  196.   if (doinbox && pmatch ("INBOX",pat)) mm_mailbox ("INBOX");
  197. }
  198.  
  199.  
  200. /* Dummy find list of all bboards
  201.  * Accepts: mail stream
  202.  *        pattern to search
  203.  */
  204.  
  205. void dummy_find_all_bboards (MAILSTREAM *stream,char *pat)
  206. {
  207.                 /* return silently */
  208. }
  209.  
  210. /* Dummy subscribe to mailbox
  211.  * Accepts: mail stream
  212.  *        mailbox to add to subscription list
  213.  * Returns: T on success, NIL on failure
  214.  */
  215.  
  216. long dummy_subscribe (MAILSTREAM *stream,char *mailbox)
  217. {
  218.   char tmp[MAILTMPLEN];
  219.   if (mailboxfile (tmp,mailbox)) return sm_subscribe (mailbox);
  220.   else return dummy_badname (tmp,mailbox);
  221. }
  222.  
  223.  
  224. /* Dummy unsubscribe to mailbox
  225.  * Accepts: mail stream
  226.  *        mailbox to delete from subscription list
  227.  * Returns: T on success, NIL on failure
  228.  */
  229.  
  230. long dummy_unsubscribe (MAILSTREAM *stream,char *mailbox)
  231. {
  232.   char tmp[MAILTMPLEN];
  233.   if (mailboxfile (tmp,mailbox)) return sm_unsubscribe (mailbox);
  234.   else return dummy_badname (tmp,mailbox);
  235. }
  236.  
  237.  
  238. /* Dummy subscribe to bboard
  239.  * Accepts: mail stream
  240.  *        bboard to add to subscription list
  241.  * Returns: T on success, NIL on failure
  242.  */
  243.  
  244. long dummy_subscribe_bboard (MAILSTREAM *stream,char *mailbox)
  245. {
  246.   return NIL;            /* always fails */
  247. }
  248.  
  249.  
  250. /* Dummy unsubscribe to bboard
  251.  * Accepts: mail stream
  252.  *        bboard to delete from subscription list
  253.  * Returns: T on success, NIL on failure
  254.  */
  255.  
  256. long dummy_unsubscribe_bboard (MAILSTREAM *stream,char *mailbox)
  257. {
  258.   return NIL;            /* always fails */
  259. }
  260.  
  261. /* Dummy create mailbox
  262.  * Accepts: mail stream
  263.  *        mailbox name to create
  264.  *        driver type to use
  265.  * Returns: T on success, NIL on failure
  266.  */
  267.  
  268. long dummy_create (MAILSTREAM *stream,char *mailbox)
  269. {
  270.   char tmp[MAILTMPLEN];
  271.   int fd;
  272.   if (!mailboxfile (tmp,mailbox)) return dummy_badname (tmp,mailbox);
  273.   if ((fd = open (tmp,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
  274.                 /* failed */
  275.     sprintf (tmp,"Can't create mailbox %s: %s",mailbox,strerror (errno));
  276.     mm_log (tmp,ERROR);
  277.     return NIL;
  278.   }
  279.   close (fd);            /* close the file */
  280.   return LONGT;            /* return success */
  281. }
  282.  
  283.  
  284. /* Dummy delete mailbox
  285.  * Accepts: mail stream
  286.  *        mailbox name to delete
  287.  * Returns: T on success, NIL on failure
  288.  */
  289.  
  290. long dummy_delete (MAILSTREAM *stream,char *mailbox)
  291. {
  292.   return dummy_rename (stream,mailbox,NIL);
  293. }
  294.  
  295.  
  296. /* Mail rename mailbox
  297.  * Accepts: mail stream
  298.  *        old mailbox name
  299.  *        new mailbox name
  300.  * Returns: T on success, NIL on failure
  301.  */
  302.  
  303. long dummy_rename (MAILSTREAM *stream,char *old,char *new)
  304. {
  305.   char tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN],lockx[MAILTMPLEN];
  306.                 /* make file name */
  307.   if (!mailboxfile (file,old)) return dummy_badname (tmp,old);
  308.   if (new && !mailboxfile (tmp,new)) return dummy_badname (tmp,new);
  309.                 /* do the rename or delete operation */
  310.   if (new ? rename (file,tmp) : unlink (file)) {
  311.     sprintf (tmp,"Can't %s mailbox %s: %s",new ? "rename" : "delete",old,
  312.          strerror (errno));
  313.     mm_log (tmp,ERROR);
  314.     return NIL;
  315.   }
  316.   return LONGT;            /* return success */
  317. }
  318.  
  319. /* Dummy open
  320.  * Accepts: stream to open
  321.  * Returns: stream on success, NIL on failure
  322.  */
  323.  
  324. MAILSTREAM *dummy_open (MAILSTREAM *stream)
  325. {
  326.   char tmp[MAILTMPLEN];
  327.   struct stat sbuf;
  328.   int fd = -1;
  329.                 /* OP_PROTOTYPE call or silence */
  330.   if (!stream || stream->silent) return NIL;
  331.   if (strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX") &&
  332.       ((fd = open (mailboxfile (tmp,stream->mailbox),O_RDONLY,NIL)) < 0))
  333.     sprintf (tmp,"%s: %s",strerror (errno),stream->mailbox);
  334.   else {
  335.     if (fd >= 0) {        /* if got a file */
  336.       fstat (fd,&sbuf);        /* sniff at its size */
  337.       close (fd);
  338.       if (sbuf.st_size) sprintf (tmp,"Not a mailbox: %s",stream->mailbox);
  339.       else fd = -1;        /* a-OK */
  340.     }
  341.     if (fd < 0) {        /* no file, right? */
  342.       if (!stream->silent) {    /* only if silence not requested */
  343.                 /* say there are 0 messages */
  344.     mail_exists (stream,(long) 0);
  345.     mail_recent (stream,(long) 0);
  346.       }
  347.       return stream;        /* return success */
  348.     }
  349.   }
  350.   if (!stream->silent) mm_log (tmp,ERROR);
  351.   return NIL;            /* always fails */
  352. }
  353.  
  354.  
  355. /* Dummy close
  356.  * Accepts: MAIL stream
  357.  */
  358.  
  359. void dummy_close (MAILSTREAM *stream)
  360. {
  361.                 /* return silently */
  362. }
  363.  
  364. /* Dummy fetch fast information
  365.  * Accepts: MAIL stream
  366.  *        sequence
  367.  */
  368.  
  369. void dummy_fetchfast (MAILSTREAM *stream,char *sequence)
  370. {
  371.   fatal ("Impossible dummy_fetchfast");
  372. }
  373.  
  374.  
  375. /* Dummy fetch flags
  376.  * Accepts: MAIL stream
  377.  *        sequence
  378.  */
  379.  
  380. void dummy_fetchflags (MAILSTREAM *stream,char *sequence)
  381. {
  382.   fatal ("Impossible dummy_fetchflags");
  383. }
  384.  
  385.  
  386. /* Dummy fetch envelope
  387.  * Accepts: MAIL stream
  388.  *        message # to fetch
  389.  *        pointer to return body
  390.  * Returns: envelope of this message, body returned in body value
  391.  */
  392.  
  393. ENVELOPE *dummy_fetchstructure (MAILSTREAM *stream,long msgno,BODY **body)
  394. {
  395.   fatal ("Impossible dummy_fetchstructure");
  396.   return NIL;
  397. }
  398.  
  399.  
  400. /* Dummy fetch message header
  401.  * Accepts: MAIL stream
  402.  *        message # to fetch
  403.  * Returns: message header in RFC822 format
  404.  */
  405.  
  406. char *dummy_fetchheader (MAILSTREAM *stream,long msgno)
  407. {
  408.   fatal ("Impossible dummy_fetchheader");
  409.   return NIL;
  410. }
  411.  
  412. /* Dummy fetch message text (body only)
  413.  * Accepts: MAIL stream
  414.  *        message # to fetch
  415.  * Returns: message text in RFC822 format
  416.  */
  417.  
  418. char *dummy_fetchtext (MAILSTREAM *stream,long msgno)
  419. {
  420.   fatal ("Impossible dummy_fetchtext");
  421.   return NIL;
  422. }
  423.  
  424.  
  425. /* Berkeley fetch message body as a structure
  426.  * Accepts: Mail stream
  427.  *        message # to fetch
  428.  *        section specifier
  429.  * Returns: pointer to section of message body
  430.  */
  431.  
  432. char *dummy_fetchbody (MAILSTREAM *stream,long m,char *sec,unsigned long *len)
  433. {
  434.   fatal ("Impossible dummy_fetchbody");
  435.   return NIL;
  436. }
  437.  
  438.  
  439. /* Dummy set flag
  440.  * Accepts: MAIL stream
  441.  *        sequence
  442.  *        flag(s)
  443.  */
  444.  
  445. void dummy_setflag (MAILSTREAM *stream,char *sequence,char *flag)
  446. {
  447.   fatal ("Impossible dummy_setflag");
  448. }
  449.  
  450.  
  451. /* Dummy clear flag
  452.  * Accepts: MAIL stream
  453.  *        sequence
  454.  *        flag(s)
  455.  */
  456.  
  457. void dummy_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
  458. {
  459.   fatal ("Impossible dummy_clearflag");
  460. }
  461.  
  462.  
  463. /* Dummy search for messages
  464.  * Accepts: MAIL stream
  465.  *        search criteria
  466.  */
  467.  
  468. void dummy_search (MAILSTREAM *stream,char *criteria)
  469. {
  470.                 /* return silently */
  471. }
  472.  
  473. /* Dummy ping mailbox
  474.  * Accepts: MAIL stream
  475.  * Returns: T if stream alive, else NIL
  476.  * No-op for readonly files, since read/writer can expunge it from under us!
  477.  */
  478.  
  479. long dummy_ping (MAILSTREAM *stream)
  480. {
  481.   char tmp[MAILTMPLEN];
  482.   MAILSTREAM *test = mail_open (NIL,stream->mailbox,OP_PROTOTYPE);
  483.                 /* swap streams if looks like a new driver */
  484.   if (test && (test->dtb != stream->dtb))
  485.     test = mail_open (stream,strcpy (tmp,stream->mailbox),NIL);
  486.   return test ? T : NIL;
  487. }
  488.  
  489.  
  490. /* Dummy check mailbox
  491.  * Accepts: MAIL stream
  492.  * No-op for readonly files, since read/writer can expunge it from under us!
  493.  */
  494.  
  495. void dummy_check (MAILSTREAM *stream)
  496. {
  497.   dummy_ping (stream);        /* invoke ping */
  498. }
  499.  
  500.  
  501. /* Dummy expunge mailbox
  502.  * Accepts: MAIL stream
  503.  */
  504.  
  505. void dummy_expunge (MAILSTREAM *stream)
  506. {
  507.                 /* return silently */
  508. }
  509.  
  510. /* Dummy copy message(s)
  511.  * Accepts: MAIL stream
  512.  *        sequence
  513.  *        destination mailbox
  514.  * Returns: T if copy successful, else NIL
  515.  */
  516.  
  517. long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
  518. {
  519.   fatal ("Impossible dummy_copy");
  520.   return NIL;
  521. }
  522.  
  523.  
  524. /* Dummy move message(s)
  525.  * Accepts: MAIL stream
  526.  *        sequence
  527.  *        destination mailbox
  528.  * Returns: T if move successful, else NIL
  529.  */
  530.  
  531. long dummy_move (MAILSTREAM *stream,char *sequence,char *mailbox)
  532. {
  533.   fatal ("Impossible dummy_move");
  534.   return NIL;
  535. }
  536.  
  537. /* Dummy append message string
  538.  * Accepts: mail stream
  539.  *        destination mailbox
  540.  *        stringstruct of message to append
  541.  * Returns: T on success, NIL on failure
  542.  */
  543.  
  544. long dummy_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
  545.            STRING *message)
  546. {
  547.   struct stat sbuf;
  548.   int fd = -1;
  549.   int e;
  550.   char tmp[MAILTMPLEN];
  551.   if ((strcmp (ucase (strcpy (tmp,mailbox)),"INBOX")) &&
  552.        ((fd = open (mailboxfile (tmp,mailbox),O_RDONLY,NIL)) < 0)) {
  553.     if ((e = errno) == ENOENT) {/* failed, was it no such file? */
  554.       mm_notify (stream,"[TRYCREATE] Must create mailbox before append",
  555.          (long) NIL);
  556.       return NIL;
  557.     }
  558.     sprintf (tmp,"%s: %s",strerror (e),mailbox);
  559.     mm_log (tmp,ERROR);        /* pass up error */
  560.     return NIL;            /* always fails */
  561.   }
  562.   else if (fd >= 0) {        /* found file? */
  563.     fstat (fd,&sbuf);        /* get its size */
  564.     close (fd);            /* toss out the fd */
  565.     if (sbuf.st_size) {        /* non-empty file? */
  566.       sprintf (tmp,"Indeterminate mailbox format: %s",mailbox);
  567.       mm_log (tmp,ERROR);
  568.       return NIL;
  569.     }
  570.   }
  571.   return (*default_proto ()->dtb->append) (stream,mailbox,flags,date,message);
  572. }
  573.  
  574.  
  575. /* Dummy garbage collect stream
  576.  * Accepts: mail stream
  577.  *        garbage collection flags
  578.  */
  579.  
  580. void dummy_gc (MAILSTREAM *stream,long gcflags)
  581. {
  582.                 /* return silently */
  583. }
  584.  
  585. /* Return bad file name error message
  586.  * Accepts: temporary buffer
  587.  *        file name
  588.  * Returns: long NIL always
  589.  */
  590.  
  591. long dummy_badname (char *tmp,char *s)
  592. {
  593.   sprintf (tmp,"Invalid mailbox name: %s",s);
  594.   mm_log (tmp,ERROR);
  595.   return (long) NIL;
  596. }
  597.